import basicTypes.C4Constant;
import Prism.core.Architecture;
import Prism.core.Component;
import Prism.core.Connector;
import Prism.core.Port;
import Prism.core.PrismConstants;
import Prism.extensions.port.ExtensiblePort;
import Prism.extensions.port.distribution.SocketDistribution;

import component.OffLineDatabase;
import component.OnLineDatabase;


// On,Off line database server
// both database is in this class because these database is in same machine and can manipulate each other
// (But now only online database component can manipulate offline one
public class OnOffLineDatabaseServer {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		onlineDatabaseServerStart();
		offlineDatabaseServerStart();
	}
	
	// OffLineDatabaseServer Program
	// this is server version of billing system to provide billing data
	// and also client version of onLineDatabase 
	public static void offlineDatabaseServerStart() {
		Architecture offLineDatabaseServerArchitecture = new Architecture();
        
        // Create offLineDatabase Component
    	Component offLineDatabaseComponent = new Component();
    	
		// Create offLineDatabase Component's implementation
    	offLineDatabaseComponent.setImplementation(new OffLineDatabase());
		
	/*
	 * Server Setup
	 */
		// Add a port to the offLineDatabase for reply requests.
		Port offLineDatabaseReplyPort = new Port(PrismConstants.REPLY);
		offLineDatabaseComponent.addPort(offLineDatabaseReplyPort);
		
		// Add offLineDatabaseComponent to offLineDatabaseServerArchitecture
		offLineDatabaseServerArchitecture.add(offLineDatabaseComponent);
		
		// Create a connector(offLineDatabaseConn) for BillingSystem
		Connector offLineDatabaseConnServer = new Connector();
		
		// Add a port to the offLineDatabaseConn for forwarding requests.
		Port offLineDatabaseConnRequestPort = new Port(PrismConstants.REQUEST);
		offLineDatabaseConnServer.addPort(offLineDatabaseConnRequestPort);
		
		// offLineDatabaseConn is extensiblePort because offLineDatabase and billing system need to be separated for huge task(redundent server too) 
		ExtensiblePort offLineDatabaseConnReplyPort = new ExtensiblePort (PrismConstants.REPLY);
		offLineDatabaseConnReplyPort.addDistribution(new SocketDistribution(C4Constant.offlineDatabasePort));           
		offLineDatabaseConnServer.addPort(offLineDatabaseConnReplyPort);
		
        // Add the BillingSystemConn to the offLineDatabaseServerArchitecture
		offLineDatabaseServerArchitecture.add(offLineDatabaseConnServer);
		
		// Weld the GUI request port to the connector reply port.
		offLineDatabaseServerArchitecture.weld(offLineDatabaseReplyPort, offLineDatabaseConnRequestPort);
		
		
	// Start this Architecture
		offLineDatabaseServerArchitecture.start();
	}
	
	// OnLineDatabaseServer Program 
	public static void onlineDatabaseServerStart() {
		Architecture onLineDatabaseServerArchitecture = new Architecture();
        
        // Create onLineDatabase Component
    	Component onLineDatabaseComponent = new Component();
    	
		// Create onLineDatabase Component's implementation
    	onLineDatabaseComponent.setImplementation(new OnLineDatabase());
		
	/*
	 * Server Setup
	 */
		// Add a port to the onLineDatabase for reply requests.
		Port onLineDatabaseReplyPort = new Port(PrismConstants.REPLY);
		onLineDatabaseComponent.addPort(onLineDatabaseReplyPort);
		
		// Add onLineDatabaseComponent to onLineDatabaseServerArchitecture
		onLineDatabaseServerArchitecture.add(onLineDatabaseComponent);
		
		// Create a connector(onLineDatabaseConn) for lower layer components
		Connector onLineDatabaseConnServer = new Connector();
		
		// Add a port to the onLineDatabaseConn for forwarding requests.
		Port onLineDatabaseConnRequestPort = new Port(PrismConstants.REQUEST);
		onLineDatabaseConnServer.addPort(onLineDatabaseConnRequestPort);
		
		// onLineDatabaseConn is extensiblePort because onLineDatabase and lower layer's components are connected by network 
		ExtensiblePort onLineDatabaseConnReplyPort = new ExtensiblePort (PrismConstants.REPLY);
		onLineDatabaseConnReplyPort.addDistribution(new SocketDistribution(C4Constant.onlineDatabasePort));           
		onLineDatabaseConnServer.addPort(onLineDatabaseConnReplyPort);
		
        // Add the BillingSystemConn to the onLineDatabaseServerArchitecture
		onLineDatabaseServerArchitecture.add(onLineDatabaseConnServer);
		
		// Weld the GUI request port to the connector reply port.
		onLineDatabaseServerArchitecture.weld(onLineDatabaseReplyPort, onLineDatabaseConnRequestPort);
		
		
	// Start this Architecture
		onLineDatabaseServerArchitecture.start();
	}
}
